<template>
  <div ref="pictureGridRef" :style="{ backgroundColor: bgColor }" class="picture-grid-container">
    <div class="grid-image">
      <div class="square-grid">
        <div v-for="i in 16" :key="`square_${i}`" class="square"></div>
      </div>
    </div>
  </div>
</template>

<!-- 安装vite-plugin-vue-setup-extend插件让<script setup>标签</script>可以直接自定义组件名 -->
<script setup lang="ts" name="PictureGrid">
import { importImage, getImageMainColor } from "@/utils/common"

const bgColor = ref("rgba(0,0,0,1)")

const setImageColorToBg = () => {
  const womanImgSrc = importImage("woman.png")
  const imgElement = document.createElement("img")
  imgElement.src = womanImgSrc
  imgElement.onload = async () => {
    const color = getImageMainColor(imgElement)
    bgColor.value = color
  }
}

onMounted(() => {
  setImageColorToBg()
})
</script>

<style lang="scss" scoped>
/**
 * $size：表示行列数，默认3
 * $gap：表示行与行、列与列之间的间距宽度，默认10px
 */
@mixin square-grid-image($size: 3, $gap: 10px) {
  .square-grid {
    width: 100vh;
    height: 100vh;
    cursor: pointer;
    display: grid;
    grid-gap: 0;
    grid-template-columns: repeat(
      $size,
      1fr
    ); // 创建 $size 列，1fr表示每列占比 1 / $size。如果 $size 为4，则表示每列占比 1/4。
    grid-template-rows: repeat(
      $size,
      1fr
    ); // 创建 $size 行，1fr表示每行占比 1 / $size。如果 $size 为4，则表示每行占比 1/4。
    transition: all ease-in-out 0.3s;

    &:hover {
      grid-gap: $gap;
    }

    .square {
      background-image: url("@/assets/images/woman.png");
      background-repeat: no-repeat;
      // 如果 $size 为 4，背景图的宽度和高度会被设置为 400%（相当于，宽高放大了3倍，也就是宽高变成了原来的4倍）。
      background-size: calc($size * 100%);

      /**
       * 列循环
       * 遍历语法：
       * @for $variable from <start> through <end>：从start值遍历到end值，包括end值。
       * @for $variable from <start> to <end>：从start值遍历到end值，不包括end值。
       */
      @for $i from 1 through $size {
        /**
         * #{$size}是一个 Sass 变量，是sass语法的插值语法，用于将变量的值插入到字符串中，:nth-child() 需要一个字符串格式的参数。
         * n: 这是一个占位符，表示一个非负整数（0, 1, 2, ...）
         * 当$size等于4，实际就是：&:nth-child(4n + 1)、&:nth-child(4n + 2)、&:nth-child(4n + 3)、&:nth-child(4n + 4)
         * 表示选择位于第 4n + 1, 4n + 2, 4n + 3, 4n + 4 处类名为square的选择器
         */
        &:nth-child(#{$size}n + #{$i}) {
          /**
           * 计算每个方块的背景图像在元素水平方向上偏移量。
           * 当background-position-x的值以 px 为单位时，它表示背景图像在水平方向上相对于元素左上角的绝对像素偏移量(绝对定位)。
           * 当background-position-x的值以 % 为单位时，是基于元素和背景图像自身的比例来定位的(相对定位)。计算方式是(元素宽度×百分比)-(放大后的背景图像宽度×百分比)。
           *
           * background-position 的%值就是图片中心点在元素内绕一圈，中心点形成的圈和元素一起形成个回字，内部的这个口字，最左边和最上边就是0%，最右边和最下边就是100%。
           *
           * 0 / 3 * 100% = 0%; // 0%表示背景图像的左边缘与元素的左边缘对齐。
           * 1 / 3 * 100% = 1 / 3 = 33.33%; // 33.33%表示背景图像的左边缘距离所在元素左边缘的距离为元素宽度的 33.33%。
           * 2 / 3 * 100% = 2 / 3 = 66.66%; // 66.66%表示背景图像的左边缘距离所在元素左边缘的距离为元素宽度的 66.66%。
           * 3 / 3 * 100% = 3 / 3 = 100%; // 100%表示背景图像的右边缘与元素的右边缘对齐。
           */
          background-position-x: calc(($i - 1) / ($size - 1) * 100%);
        }
      }

      // 行循环
      @for $i from 1 through $size {
        /**
         * 当$size等于4，实际就是：
         * &:nth-child(n + 1):nth-child(-n + 4)   // 先通过 :nth-child(n + 1) 选中所有子元素，再通过 :nth-child(-n + 4) 进一步筛选出前 4 个子元素，相当于取了一个交集，最终只选择父元素下从第 1 个到第 4 个的子元素。
         * &:nth-child(n + 5):nth-child(-n + 8)   // 先通过:nth-child(n + 5) 筛选出第 5 个及之后的元素，再通过:nth-child(-n + 8) 在这些元素里进一步筛选出前 8 个元素，取了一个交集，最终取到的是第 5 个到第 8 个的子元素。
         * &:nth-child(n + 9):nth-child(-n + 12)  // 表示选择父元素下位置处于第 9 个到第 12 个的子元素
         * &:nth-child(n + 13):nth-child(-n + 16) // 表示选择父元素下位置处于第 13 个到第 16 个的子元素
        */
        &:nth-child(n + #{($i - 1) * $size + 1}):nth-child(-n + #{$i * $size}) {
          /**
           * 计算每个方块的背景图像在元素垂直方向上偏移量。
           * 第1张方块图片放大后仍然是第1张方块图片，y坐标仍然是0，所以后面的第2、3、4列的方块图片的y坐标计算需要排除掉了第一张图片的y坐标这一项（也就是 $size - 1）后再进行均分。
           */
          background-position-y: calc(($i - 1) / ($size - 1) * 100%);
        }
      }
    }
  }
}

.picture-grid-container {
  width: 100%;
  height: 100vh;
  background-color: #000000;
  display: flex;
  justify-content: center;
  align-items: center;
  .grid-image {
    @include square-grid-image(4);
  }
}
</style>
